package com.haust.leyou.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.haust.leyou.bo.SpuBo;
import com.haust.leyou.mapper.*;
import com.haust.leyou.pojo.*;
import com.haust.leyou.vo.PageResult;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Auther: csp1999
 * @Date: 2020/12/11/11:04
 * @Description:
 */
@Service
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private GoodsService goodsService;

    // amqp消息模板
    @Autowired
    private AmqpTemplate amqpTemplate;

    /**
     * 根据条件分页查询是spu
     *
     * @param key      查询的关键字
     * @param saleable 是否上架：0下架/1上架/null全部商品
     * @param page     当前页
     * @param rows     每页数据数量
     * @return
     */
    public PageResult<SpuBo> querySpuByPage(String key, Boolean saleable, Integer page, Integer rows) {

        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();

        // 1.添加查询条件
        if (key != null || key != "") {
            criteria.andLike("title", "%" + key + "%");
        }
        // 2.添加上下架的过滤条件
        if (saleable != null) {
            criteria.andEqualTo("saleable", saleable);
        }

        // 添加分页
        PageHelper.startPage(page, rows);

        // 执行查询，获取spu 集合
        List<Spu> spuList = spuMapper.selectByExample(example);
        PageInfo pageInfo = new PageInfo(spuList);

        // spu 集合转化成spubo集合
        List<SpuBo> spuBoList = spuList.stream().map(spu -> {
            SpuBo spuBo = new SpuBo();
            BeanUtils.copyProperties(spu, spuBo);

            // 查询品牌名称
            Brand brand = brandMapper.selectByPrimaryKey(spu.getBrandId());
            spuBo.setBname(brand.getName());
            // 查询分类名称
            List<String> cnameList = categoryService.queryNamesByIds(
                    Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));

            // 将cnameList集合设置为spuBo的cname名称，多个分类名称以'-'分割
            spuBo.setCname(StringUtils.join(cnameList, "-"));

            return spuBo;
        }).collect(Collectors.toList());

        // 返回pageResult
        return new PageResult<>(pageInfo.getTotal(), spuBoList);
    }

    /**
     * 新增商品：需要先后向四张表中增数据
     * 1.tb_spu
     * 2.tb_spu_detail
     * 3.tb_sku
     * 4.tb_stock
     *
     * @param spuBo
     */
    @Transactional
    public void saveGoods(SpuBo spuBo) {

        // 1.先新增spu
        // 设置默认值
        spuBo.setId(null);
        spuBo.setSaleable(true);
        spuBo.setValid(true);
        spuBo.setCreateTime(new Date());
        spuBo.setLastUpdateTime(spuBo.getCreateTime());
        spuMapper.insertSelective(spuBo);

        // 2.再去新增spuDetail
        SpuDetail spuDetail = spuBo.getSpuDetail();
        spuDetail.setSpuId(spuBo.getId());
        spuDetailMapper.insertSelective(spuDetail);

//        // 遍历sku 集合
//        spuBo.getSkus().forEach(sku -> {
//            // 3.新增sku
//            // 设置默认值
//            sku.setId(null);
//            sku.setSpuId(spuBo.getId());
//            sku.setCreateTime(new Date());
//            sku.setLastUpdateTime(sku.getCreateTime());
//            skuMapper.insertSelective(sku);
//
//            // 4.新增stock
//            Stock stock = new Stock();
//            stock.setSkuId(sku.getId());
//            stock.setStock(sku.getStock());
//            stockMapper.insertSelective(stock);
//        });

        // 保存sku和库存信息
        saveSkuAndStock(spuBo);

        // 发送消息到mq
        sendMsg("insert", spuBo.getId());
    }

    // 发送消息到mq
    private void sendMsg(String type, Long id) {
        try {
            amqpTemplate.convertAndSend("item." + type, id);
        } catch (AmqpException e) {
            e.printStackTrace();
        }
    }

    /**
     * 更新商品数据：
     * <p>
     * 数据库表的操作顺序：
     * tb_stock--->tb_sku--->tb_sku--->tb_stock--->tb_spu--->tb_spu_detail
     *
     * @param spuBo
     */
    @Transactional
    public void updateGoods(SpuBo spuBo) {
        // 根据spuId 查询要删除的sku 集合
        Sku record = new Sku();
        record.setSpuId(spuBo.getId());
        List<Sku> skuList = skuMapper.select(record);

        // 遍历skuList,逐个删除sku 中的stock
        skuList.forEach(sku -> {
            // 1.删除tb_stock 表中对应的stock
            stockMapper.deleteByPrimaryKey(sku.getId());
        });

        // 2.删除tb_sku 表中对应的sku
        // 根据spuId 删除sku 集合
        Sku sku = new Sku();
        sku.setSpuId(spuBo.getId());
        skuMapper.delete(sku);

        // 3.新增tb_sku 表中对应的sku
        // 4.新增tb_stock 表中对应的stock
        this.saveSkuAndStock(spuBo);

        // 5.更新tb_spu 表中对应的spu 和 tb_spu_detail 表中对应的spuDetail
        // 不能随便更新的字段设置为null,确保前端传哪些就只更新必要的数据
        spuBo.setCreateTime(null);
        spuBo.setLastUpdateTime(new Date());
        spuBo.setValid(null);
        spuBo.setSaleable(null);
        spuMapper.updateByPrimaryKeySelective(spuBo);

        spuDetailMapper.updateByPrimaryKeySelective(spuBo.getSpuDetail());

        // 发送消息到mq
        sendMsg("update",spuBo.getId());
    }

    // 新增sku 并 新增stock
    private void saveSkuAndStock(SpuBo spuBo) {
        spuBo.getSkus().forEach(sku -> {
            // 新增sku
            sku.setId(null);
            sku.setSpuId(spuBo.getId());
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(sku.getCreateTime());
            skuMapper.insertSelective(sku);

            // 新增stock
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
            stockMapper.insertSelective(stock);
        });
    }

    /**
     * 根据spuId 查询spuDetail: 用于商品编辑的数据回显
     *
     * @param spuId
     * @return
     */
    public SpuDetail querySpuDetailBySpuId(Long spuId) {

        return spuDetailMapper.selectByPrimaryKey(spuId);
    }

    /**
     * 根据spuId 查询sku 集合：用于商品编辑的数据回显
     *
     * @param spuId
     * @return
     */
    public List<Sku> querySkusBySpuId(Long spuId) {

        Sku record = new Sku();
        record.setSpuId(spuId);

        List<Sku> skuList = skuMapper.select(record);

        // 依次遍历sku，根据skuId 拿到商品库存stock
        skuList.forEach(sku -> {
            Stock stock = stockMapper.selectByPrimaryKey(sku.getId());
            sku.setStock(stock.getStock());
        });

        return skuList;
    }

    /**
     * 根据spuId 查询Spu
     *
     * @param id
     * @return
     */
    public Spu querySpuById(Long id) {

        return spuMapper.selectByPrimaryKey(id);
    }

    /**
     * 根据skuId 查询sku
     *
     * @param skuId
     * @return
     */
    public Sku querySkuBySkuId(Long skuId) {

        return skuMapper.selectByPrimaryKey(skuId);
    }
}
